package cn.bugstack.service.impl;

import cn.bugstack.domain.po.WeixinTemplateMessageVO;
import cn.bugstack.domain.req.WeixinQrCodeReq;
import cn.bugstack.domain.res.WeixinQrCodeRes;
import cn.bugstack.domain.res.WeixinTokenRes;
import cn.bugstack.service.ILoginService;
import cn.bugstack.service.weixin.IWeixinApiService;
import com.google.common.cache.Cache;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import retrofit2.Call;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Fuzhengwei bugstack.cn @小傅哥
 * @description 微信服务
 * @create 2024-09-28 13:46
 */
@Service
public class WeixinLoginServiceImpl implements ILoginService {

    @Value("${weixin.config.app-id}")
    private String appid;
    @Value("${weixin.config.app-secret}")
    private String appSecret;
    @Value("${weixin.config.template_id}")
    private String template_id;

    private static final String KEY_ACCESS_TOKEN = "wx:accessToken:";
    private static final String KEY_LOGIN_TICKET = "wx:login:ticket:";

    private final RedissonClient redissonClient;

    public WeixinLoginServiceImpl(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    @Resource
    private Cache<String, String> weixinAccessToken;
    @Resource
    private IWeixinApiService weixinApiService;
    @Resource
    private Cache<String, String> openidToken;



    @Override
    public String createQrCodeTicket() throws Exception {
        // 1. 获取 accessToken API调用授权：调用微信所有API接口都需要携带accessToken
//        String accessToken = weixinAccessToken.getIfPresent(appid);
        RBucket<String> accessTokenBucket = redissonClient.getBucket(KEY_ACCESS_TOKEN + appid);
        String accessToken = accessTokenBucket.get();


        if (null == accessToken) {
            Call<WeixinTokenRes> call = weixinApiService.getToken("client_credential", appid, appSecret);
            WeixinTokenRes weixinTokenRes = call.execute().body();
            assert weixinTokenRes != null;
            accessToken = weixinTokenRes.getAccess_token();
//            weixinAccessToken.put(appid, accessToken);
            accessTokenBucket.set(accessToken, 7000, TimeUnit.SECONDS);
        }

        // 2. 生成 ticket
        WeixinQrCodeReq weixinQrCodeReq = WeixinQrCodeReq.builder()
                .expire_seconds(2592000)
                .action_name(WeixinQrCodeReq.ActionNameTypeVO.QR_SCENE.getCode())
                .action_info(WeixinQrCodeReq.ActionInfo.builder()
                        .scene(WeixinQrCodeReq.ActionInfo.Scene.builder()
                                .scene_id(100601)
                                .build())
                        .build())
                .build();

        Call<WeixinQrCodeRes> call = weixinApiService.createQrCode(accessToken, weixinQrCodeReq);
        WeixinQrCodeRes weixinQrCodeRes = call.execute().body();
        assert null != weixinQrCodeRes;
        return weixinQrCodeRes.getTicket();
    }

    @Override
    public String checkLogin(String ticket) {
        RBucket<String> loginBucket = redissonClient.getBucket(KEY_LOGIN_TICKET + ticket);
        System.out.println("保存登录状态时的 key = " + loginBucket.get());
        return loginBucket.get();
    }
    @Override
    public void saveLoginState(String ticket, String openid) throws IOException {
        RBucket<String> loginBucket = redissonClient.getBucket(KEY_LOGIN_TICKET + ticket);
        loginBucket.set(openid, 30, TimeUnit.MINUTES);
        String key = KEY_LOGIN_TICKET + ticket;
        System.out.println("保存登录状态时的 key = " + key);
        System.out.println("检测登录状态时的 key = " + key);

        // 1. 获取 accessToken 【实际业务场景，按需处理下异常】
//        String accessToken = weixinAccessToken.getIfPresent(appid);
        RBucket<String> accessTokenBucket = redissonClient.getBucket(KEY_ACCESS_TOKEN + appid);
        String accessToken = accessTokenBucket.get();
        if (accessToken == null) {
            Call<WeixinTokenRes> call = weixinApiService.getToken("client_credential", appid, appSecret);
            WeixinTokenRes weixinTokenRes = call.execute().body();
            assert weixinTokenRes != null;
            accessToken = weixinTokenRes.getAccess_token();
            accessTokenBucket.set(accessToken, 7000, TimeUnit.SECONDS);
        }

        // 2. 发送模板消息
        Map<String, Map<String, String>> data = new HashMap<>();
        WeixinTemplateMessageVO.put(data, WeixinTemplateMessageVO.TemplateKey.USER, openid);

        WeixinTemplateMessageVO templateMessageDTO = new WeixinTemplateMessageVO(openid, template_id);
        templateMessageDTO.setUrl("https://gaga.plus");
        templateMessageDTO.setData(data);

        Call<Void> call = weixinApiService.sendMessage(accessToken, templateMessageDTO);
        call.execute();

    }

}
